package tipos;

/**
 *
 * Classe que representa o domínio cpf.
 * @author Thiago Stuckert
 **/
public class Cpf {

    /**
     * Constante TAM_CPF representa o tamanho do CPF.
     */
    private static final int TAM_CPF = 11;

    /**
     *  O método validar é responsável por validar um determinado cpf.
     *  cpf é uma string de 11 digitos, sendo os dois últimos de validação.
     *  Cpf sem traco.
     *  Verificação baseada neste link:
     *  http://imasters.uol.com.br/artigo/2410/javascript/algoritmo_do_cpf/
     *  Testado através do Junit na classe CpfTest.java
     *
     * @param cpf Corresponde ao cpf a ser validado
     * @exception NullPointerException
     * @exception IllegalArgumentException
     */

    public static void validar(final String cpf) {
        if (cpf == null) {
            throw new NullPointerException("Cpf nulo.");
        }
        if (cpf.length() != TAM_CPF) {
            throw new IllegalArgumentException("Cpf com tamanho inválido.");
        }

         /*obtem o primeiro digito verificador*/
         for (int i = 0; i < TAM_CPF; i++) {
           if (!Character.isDigit(cpf.charAt(i))) {
               throw new IllegalArgumentException("Cpf contem caracteres"
                       + " que nao sao digitos.");
           }
         }

        int soma = 0, num;
        int m = TAM_CPF - 1;

         /*obtem o primeiro digito verificador*/
         for (int i = 0; i < (TAM_CPF - 2); i++, m--) {
             num = Integer.parseInt("" + cpf.charAt(i));
             soma += (num * m);
         }
         int primeiroDigitoVerificador = soma % TAM_CPF;

         if (primeiroDigitoVerificador < 2) {
             primeiroDigitoVerificador = 0;
         } else {
             primeiroDigitoVerificador = TAM_CPF - primeiroDigitoVerificador;
         }

         /*Verifica se o primeiro digito calculado eh igual ao informado*/
         num = Integer.parseInt("" + cpf.charAt((TAM_CPF - 2)));
         if (primeiroDigitoVerificador != num) {
             throw new IllegalArgumentException("Cpf primeiro digito"
                     + " validador incorreto: " + cpf + ".");
         }
         /*Calcula o segundo digito verificador*/
         int segundoDigitoVerificador = soma + 2 * primeiroDigitoVerificador;

         /*obtem o primeiro digito verificador*/
         for (int i = 0; i < TAM_CPF - 2; i++) {
             num = Integer.parseInt("" + cpf.charAt(i));
             segundoDigitoVerificador += num;
        }

         segundoDigitoVerificador %= TAM_CPF;
         if (segundoDigitoVerificador < 2) {
             segundoDigitoVerificador = 0;
         } else {
             segundoDigitoVerificador = TAM_CPF - segundoDigitoVerificador;
         }

         /*Verifica se o segundo digito calculado eh igual ao informado*/
         num = Integer.parseInt("" + cpf.charAt(TAM_CPF - 1));
         if (segundoDigitoVerificador != num) {
             throw new IllegalArgumentException("Cpf segundo digito validador "
                     + "incorreto: " + cpf + ".");
         }
    }
}
